Our policy interface enables managers to create a single binary policy file in a trusted
environment and distributed it to multiple systems for enforcement.
+5. Booting with a binary policy:
+********************************
+The grub configuration file can be adapted to boot the hypervisor with an
+already active policy. To do this, a binary policy file - this can be
+the same file as used by the policy_tool - should be placed into the boot
+partition. The following entry from the grub configuration file shows how
+a binary policy can be added to the system during boot time. Note that the
+binary policy must be of the same type that the hypervisor was compiled
+for. The policy module line should also only be added as the last module
+line if XEN was compiled with the access control module (ACM).
+
+title XEN0 3.0 Devel
+ kernel /xen.gz dom0_mem=400000
+ module /vmlinuz-2.6.12-xen0 root=/dev/hda2 ro console=tty0
+ module /initrd-2.6.12-xen0.img
+ module /xen_sample_policy.bin
+
+
====================end-of file=======================================
final short binaryBufferHeaderSz = (3 * u32Size + 4* u16Size);
/* copied directlty from policy_ops.h */
- final int POLICY_INTERFACE_VERSION = 0xAAAA0002;
+ final int POLICY_INTERFACE_VERSION = 0xAAAA0003;
/* copied directly from acm.h */
final int ACM_MAGIC = 0x0001debc;
* Author:
* Reiner Sailer <sailer@watson.ibm.com>
*
+ * Contributors:
+ * Stefan Berger <stefanb@watson.ibm.com>
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
#include <xen/lib.h>
#include <xen/delay.h>
#include <xen/sched.h>
+#include <xen/multiboot.h>
#include <acm/acm_hooks.h>
#include <acm/acm_endian.h>
acm_bin_pol.secondary_binary_policy = secondary;
}
+static int
+acm_setup(unsigned int *initrdidx,
+ const multiboot_info_t *mbi,
+ unsigned long initial_images_start)
+{
+ int i;
+ module_t *mod = (module_t *)__va(mbi->mods_addr);
+ int rc = ACM_OK;
+
+ if (mbi->mods_count > 1)
+ *initrdidx = 1;
+
+ /*
+ * Try all modules and see whichever could be the binary policy.
+ * Adjust the initrdidx if module[1] is the binary policy.
+ */
+ for (i = mbi->mods_count-1; i >= 1; i--) {
+ struct acm_policy_buffer *pol;
+ char *_policy_start;
+ unsigned long _policy_len;
+#if defined(__i386__)
+ _policy_start = (char *)(initial_images_start + (mod[i].mod_start-mod[0].mod_start));
+#elif defined(__x86_64__)
+ _policy_start = __va(initial_images_start + (mod[i].mod_start-mod[0].mod_start));
+#else
+#error Architecture unsupported by sHype
+#endif
+ _policy_len = mod[i].mod_end - mod[i].mod_start;
+ if (_policy_len < sizeof(struct acm_policy_buffer))
+ continue; /* not a policy */
+
+ pol = (struct acm_policy_buffer *)_policy_start;
+ if (ntohl(pol->magic) == ACM_MAGIC) {
+ rc = acm_set_policy((void *)_policy_start,
+ (u16)_policy_len,
+ ACM_USE_SECURITY_POLICY,
+ 0);
+ if (rc == ACM_OK) {
+ printf("Policy len 0x%lx, start at %p.\n",_policy_len,_policy_start);
+ if (i == 1) {
+ if (mbi->mods_count > 2) {
+ *initrdidx = 2;
+ } else {
+ *initrdidx = 0;
+ }
+ } else {
+ *initrdidx = 1;
+ }
+ break;
+ } else {
+ printk("Invalid policy. %d.th module line.\n", i+1);
+ }
+ } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == ACM_MAGIC ) */
+ }
+ return rc;
+}
+
int
-acm_init(void)
+acm_init(unsigned int *initrdidx,
+ const multiboot_info_t *mbi,
+ unsigned long initial_images_start)
{
int ret = -EINVAL;
if (ret != ACM_OK)
return -EINVAL;
+ acm_setup(initrdidx, mbi, initial_images_start);
printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__,
ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
- return ACM_OK;
+ return ret;
}
+
#endif
int
#include <acm/acm_endian.h>
int
-acm_set_policy(void *buf, u16 buf_size, u16 policy)
+acm_set_policy(void *buf, u16 buf_size, u16 policy, int isuserbuffer)
{
u8 *policy_buffer = NULL;
struct acm_policy_buffer *pol;
/* 1. copy buffer from domain */
if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
goto error_free;
- if (copy_from_user(policy_buffer, buf, buf_size)) {
- printk("%s: Error copying!\n",__func__);
- goto error_free;
+ if (isuserbuffer) {
+ if (copy_from_user(policy_buffer, buf, buf_size)) {
+ printk("%s: Error copying!\n",__func__);
+ goto error_free;
+ }
+ } else {
+ memcpy(policy_buffer, buf, buf_size);
}
/* 2. some sanity checking */
pol = (struct acm_policy_buffer *)policy_buffer;
if ((ntohl(pol->magic) != ACM_MAGIC) ||
(ntohs(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
- (ntohs(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) {
+ (ntohs(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code) ||
+ (ntohl(pol->policyversion) != POLICY_INTERFACE_VERSION)) {
printkd("%s: Wrong policy magics!\n", __func__);
goto error_free;
}
module_t *mod = (module_t *)__va(mbi->mods_addr);
unsigned long firsthole_start, nr_pages;
unsigned long initial_images_start, initial_images_end;
+ unsigned long _initrd_start = 0, _initrd_len = 0;
+ unsigned int initrdidx = 1;
struct e820entry e820_raw[E820MAX];
int i, e820_raw_nr = 0, bytes = 0;
struct ns16550_defaults ns16550 = {
shadow_mode_init();
/* initialize access control security module */
- acm_init();
+ acm_init(&initrdidx, mbi, initial_images_start);
/* Create initial domain 0. */
dom0 = do_createdomain(0, 0);
}
}
+ if ( (initrdidx > 0) && (initrdidx < mbi->mods_count) )
+ {
+ _initrd_start = initial_images_start +
+ (mod[initrdidx].mod_start - mod[0].mod_start);
+ _initrd_len = mod[initrdidx].mod_end - mod[initrdidx].mod_start;
+ }
+
/*
* We're going to setup domain0 using the module(s) that we stashed safely
* above our heap. The second module, if present, is an initrd ramdisk.
if ( construct_dom0(dom0,
initial_images_start,
mod[0].mod_end-mod[0].mod_start,
- (mbi->mods_count == 1) ? 0 :
- initial_images_start +
- (mod[1].mod_start-mod[0].mod_start),
- (mbi->mods_count == 1) ? 0 :
- mod[mbi->mods_count-1].mod_end - mod[1].mod_start,
+ _initrd_start,
+ _initrd_len,
cmdline) != 0)
panic("Could not set up DOM0 guest OS\n");
.quad do_boot_vcpu
.quad do_set_segment_base /* 25 */
.quad do_mmuext_op
+ .quad do_policy_op
.rept NR_hypercalls-((.-hypercall_table)/4)
.quad do_ni_hypercall
.endr
#else
-/* function prototypes defined in acm/acm_policy.c */
-int acm_set_policy(void *buf, u16 buf_size, u16 policy);
-int acm_get_policy(void *buf, u16 buf_size);
-int acm_dump_statistics(void *buf, u16 buf_size);
-
typedef enum policyoperation {
POLICY, /* access to policy interface (early drop) */
GETPOLICY, /* dump policy cache */
ret = acm_set_policy(
op->u.setpolicy.pushcache,
op->u.setpolicy.pushcache_size,
- op->u.setpolicy.policy_type);
+ op->u.setpolicy.policy_type,
+ 1);
if (ret == ACM_OK)
ret = 0;
else
/* protos */
int acm_init_domain_ssid(domid_t id, ssidref_t ssidref);
int acm_free_domain_ssid(struct acm_ssid_domain *ssid);
+int acm_set_policy(void *buf, u16 buf_size, u16 policy, int isuserbuffer);
+int acm_get_policy(void *buf, u16 buf_size);
+int acm_dump_statistics(void *buf, u16 buf_size);
#endif
#include <xen/lib.h>
#include <xen/delay.h>
#include <xen/sched.h>
+#include <xen/multiboot.h>
#include <public/acm.h>
#include <acm/acm_core.h>
#include <public/dom0_ops.h>
{ return 0; }
static inline int acm_pre_grant_setup(domid_t id)
{ return 0; }
-static inline int acm_init(void)
+static inline int acm_init(unsigned int *initrdidx,
+ const multiboot_info_t *mbi,
+ unsigned long start)
{ return 0; }
static inline void acm_post_domain0_create(domid_t domid)
{ return; }
acm_post_domain_create(domid, ACM_DOM0_SSIDREF);
}
-extern int acm_init(void);
+extern int acm_init(unsigned int *initrdidx,
+ const multiboot_info_t *mbi,
+ unsigned long start);
#endif